﻿using System;
using System.Linq;
using System.Data;
using System.Security;
using System.Web.UI.HtmlControls;
using System.Configuration;
using System.Web;
using System.Web.Routing;
using System.Text;

namespace MakeItWeb.Framework
{
    public class MakeItWebAdminPage : MakeItWebPage
    {
        public MakeItWebAdminPage()
        {
            this.Theme = "Default";
        }

        protected override void OnInitComplete(EventArgs e)
        {
            base.OnInitComplete(e);
            if (!Page.User.Identity.IsAuthenticated)
                Response.Redirect("/Login", true);

            if (!IsInRole("Administrator"))
                throw new SecurityException();
        }
    }

    public class MakeItWebAuthenticatedUserPage : MakeItWebPage
    {
        protected override void OnInitComplete(EventArgs e)
        {
            base.OnInitComplete(e);
            if (!Page.User.Identity.IsAuthenticated)
            {
                Response.Redirect(string.Format("/Login?Redirect={0}", Server.UrlPathEncode(Request.RawUrl)), true);
            }

            if (!IsInRole("AuthenticatedUser"))
                throw new SecurityException();
        }
    }

    public class MakeItWebPage : System.Web.UI.Page, IMakeItWebControl
    {
        protected HtmlPage m_oHtmlPage = new HtmlPage();
        private bool m_bUseQueryString = false;

        public MakeItWebPage()
        {
            this.Theme = "Default";
        }

        protected override void OnPreInit(EventArgs e)
        {
            base.OnPreInit(e);
            if (m_bUseQueryString)
                m_oHtmlPage = HtmlPage.GetPageDetail(Request.RawUrl);
            else if (this is IDynamicPage)
            {
                string sPageCd = GetQueryString("PageCd");
                if (!string.IsNullOrEmpty(sPageCd))
                {
                    string sAbsoluteUrl = GetAbsoluteUrl(sPageCd);
                    m_oHtmlPage = HtmlPage.GetPageDetail(sAbsoluteUrl);
                }
            }
            else
                m_oHtmlPage = HtmlPage.GetPageDetail(Request.Url.AbsolutePath);

            if (!string.IsNullOrEmpty(m_oHtmlPage.Role) && !IsInRole(m_oHtmlPage.Role))
            {
                if (User.Identity.IsAuthenticated)
                    Response.Redirect("/Unauthroized.aspx", true);
                else
                    Response.Redirect(string.Format("/Login?Redirect={0}", Server.UrlPathEncode(Request.RawUrl)), true);
            }

            this.Title = string.IsNullOrEmpty(m_oHtmlPage.HtmlTitleTxt) ? ConfigurationManager.AppSettings["DefaultSiteTitle"] : m_oHtmlPage.HtmlTitleTxt;
        }

        private string GetAbsoluteUrl(string sPageCd)
        {
            try
            {
                Guid guid = new Guid(sPageCd);
                return GetAbsoluteUrl(guid);
            }
            catch (Exception)
            {
                StoredProcArgs args = new StoredProcArgs();
                args["pNodeCd"] = sPageCd;
                args["pGenericPageType"] = GetPageTypeName();
                using (DataSet ds = GenericQry.GetDataSet("proc_cm_GetSiteMapNode", args))
                {
                    if (ds.Tables[0].Rows.Count > 0)
                        return GetAbsoluteUrl((Guid)ds.Tables[0].Rows[0]["node_id"]);
                }

                return GetAbsoluteUrl(Guid.Empty);
            }
        }

        private string GetPageTypeName()
        {
            if (this is IDynamicPage)
                return (this as IDynamicPage).PageTypeName;

            return string.Empty;
        }

        private string GetAbsoluteUrl(Guid guidPageCd)
        {
            if (HttpContext.Current.Request.RequestContext.RouteData != null)
            {
                var routeHandler = Request.RequestContext.RouteData.RouteHandler as System.Web.Routing.PageRouteHandler;
                if (routeHandler != null)
                {
                    StringBuilder sb = new StringBuilder();
                    Array.ForEach(HttpContext.Current.Request.RequestContext.RouteData.Values.ToArray(), kvp =>
                    {
                        sb.AppendFormat("{0}={1}&", kvp.Key, kvp.Key == "PageCd" ? guidPageCd : kvp.Value);
                    });

                    return System.Web.VirtualPathUtility.ToAbsolute(string.Format("{0}{1}{2}"
                        , routeHandler.VirtualPath
                        , sb.Length == 0 ? string.Empty : "?"
                        , sb.Length == 0 ? string.Empty : sb.ToString(0, sb.Length - 1)));
                }
            }
            return string.Format("{0}?PageCd={1}", Request.Url.AbsolutePath, guidPageCd);
        }

        public static string GetQueryString(string sKey)
        {
            if (HttpContext.Current.Request.RequestContext.RouteData != null)
            {
                if (HttpContext.Current.Request.RequestContext.RouteData.Values.ContainsKey(sKey))
                    return HttpContext.Current.Request.RequestContext.RouteData.Values[sKey].ToString();
            }

            return HttpContext.Current.Request.QueryString["PageCd"];
        }

        public HtmlPage CurrentHtmlPage
        {
            get { return m_oHtmlPage; }
        }

        public bool UseQueryString
        {
            get { return m_bUseQueryString; }
            set { m_bUseQueryString = value; }
        }

        public string CurrentUserName
        {
            get
            {
                // TODO: Implement impersonation
                return Page.User.Identity.Name;
            }
        }

        private Member _CurrentMember = null;
        public Member CurrentMember
        {
            get
            {
                if (!User.Identity.IsAuthenticated)
                    return null;

                if (_CurrentMember == null)
                    _CurrentMember = Member.GetMember(CurrentUserName);

                return _CurrentMember;
            }
        }

        public bool WebOnlyMemberInd
        {
            get
            {
                // TODO: Implement this property getter
                throw new NotImplementedException();
            }
        }

        public bool DisplayMemberSearchInd
        {
            get
            {
                // TODO: Implement this property getter
                throw new NotImplementedException();
            }
            set
            {
                // TODO: Implement this property setter
                throw new NotImplementedException();
            }
        }

        public virtual bool DisplayDynamicBackgroundForAdmin
        {
            get { return true; }
        }

        public bool IsInRole(string sRoleName)
        {
            if (User.IsInRole("SystemAdministrator"))
                return true;

            return User.IsInRole(sRoleName);
        }

        public virtual bool IsPageAdministrator()
        {
            if (IsInRole("Administrator"))
                return true;

            if (Page is IDynamicPage)
            {
                //TODO - optimization is required for calling this in one shot
                StoredProcArgs args = new StoredProcArgs();
                string sPageCd = GetQueryString("PageCd");
                Guid guidPageCd = Guid.Empty;
                try
                {
                    guidPageCd = new Guid(sPageCd);
                    args["pNodeId"] = guidPageCd;
                }
                catch(Exception)
                {
                    args["pNodeCd"] = sPageCd;
                    args["pGenericPageType"] = GetPageTypeName();
                }
                using (DataSet ds = GenericQry.GetDataSet("proc_cm_GetSiteMapNode", args))
                {
                    if (ds.Tables[0].Rows.Count == 0 || ds.Tables[0].Rows[0].IsNull("admin_users"))
                        return false;

                    string[] aAdminUsers = ds.Tables[0].Rows[0]["admin_users"].ToString().ToLower().Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                    if (aAdminUsers.Contains(User.Identity.Name.ToLower()))
                        return true;
                }
            }

            return false;
        }

        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);

            // add meta keywords if content is available
            HtmlMeta oMetaKeyword = new HtmlMeta();
            oMetaKeyword.Name = "Keywords";
            if (string.IsNullOrEmpty(m_oHtmlPage.MetaKeywordTxt) == false)
                oMetaKeyword.Content = m_oHtmlPage.MetaKeywordTxt;
            else if (string.IsNullOrEmpty(ConfigurationManager.AppSettings["DefaultSiteKeywords"]) == false)
                oMetaKeyword.Content = ConfigurationManager.AppSettings["DefaultSiteKeywords"];
            if (string.IsNullOrEmpty(oMetaKeyword.Content) == false)
                Header.Controls.Add(oMetaKeyword);

            // add meta description if content is available
            HtmlMeta oMetaDescription = new HtmlMeta();
            oMetaDescription.Name = "Description";
            if (string.IsNullOrEmpty(m_oHtmlPage.MetaDescriptionTxt) == false)
                oMetaDescription.Content = m_oHtmlPage.MetaDescriptionTxt;
            else if (string.IsNullOrEmpty(ConfigurationManager.AppSettings["DefaultSiteDescription"]) == false)
                oMetaDescription.Content = ConfigurationManager.AppSettings["DefaultSiteDescription"];
            if (string.IsNullOrEmpty(oMetaDescription.Content) == false)
                Header.Controls.Add(oMetaDescription);

            if (m_oHtmlPage.MetaNofollowInd || m_oHtmlPage.MetaNoindexInd)
            {
                HtmlMeta oMetaRobots = new HtmlMeta();
                oMetaRobots.Name = "ROBOTS";
                if (m_oHtmlPage.MetaNoindexInd && m_oHtmlPage.MetaNofollowInd)
                    oMetaRobots.Content = "NOINDEX, NOFOLLOW";
                else if (m_oHtmlPage.MetaNofollowInd)
                    oMetaRobots.Content = "NOFOLLOW";
                else if (m_oHtmlPage.MetaNoindexInd)
                    oMetaRobots.Content = "NOINDEX";
                Header.Controls.Add(oMetaRobots);
            }
            if (m_oHtmlPage.MetaNoarchiveInd)
            {
                HtmlMeta oMetaGooglebot = new HtmlMeta();
                oMetaGooglebot.Name = "GOOGLEBOT";
                oMetaGooglebot.Content = "NOARCHIVE";
                Header.Controls.Add(oMetaGooglebot);
            }
        }

        public void RegisterAdminFunction(string sText, string sNavigationUrl, string sIconImageUrl)
        {
            (Master as IMakeItWebControl).RegisterAdminFunction(sText, sNavigationUrl, sIconImageUrl);
        }

        public void ClearAdminFunctions()
        {
            (Master as IMakeItWebControl).ClearAdminFunctions();
        }

        public virtual string SelectedSection
        {
            get { return string.Empty; }
        }
    }
}